ElastiCacheをセキュアに運用できてますか?Redis認証トークンの変更をサポートしましたよ! #reinvent
こんにちは(U・ω・U)
着々とElastiCacheおじさんへの道を歩んでいる深澤です。
立派なElastiCacheおじさんに成長することを決意したラスベガスでの出来事でした。
— 深澤俊 (@shun_quartet) December 4, 2019
さて、僕はラスベガスで開催されたre:Invent 2019にて「Whatʼs new with Amazon ElastiCache」というセッションに参加してきました。
このセッションで「認証トークンの変更をサポートした」と聞きました。ElastiCacheではこれまで認証トークンは構築時に設定できるものの、一回設定したら変更不可でした。なので認証トークンを変更したいなと思ったらクラスターから再作成しなければならなかったのですが、今回のアップデートによりその必要がなくなったということでしょうか。早速実際に動かしてその挙動を確認していきたいと思います!
まずはクラスター構築
以下のコマンドでクラスターを構築します。
aws elasticache create-replication-group \ --replication-group-id test-modify-authkey \ --replication-group-description "Test the Elasticache supports changing the authentication token" \ --engine redis \ --engine-version 5.0.6 \ --cache-node-type cache.t2.micro \ --num-node-groups 1 \ --replicas-per-node-group 2 \ --cache-parameter-group default.redis5.0 \ --transit-encryption-enabled \ --auth-token this-is-a-test-token \ --cache-subnet-group test-redis-subnet \ --security-group-ids test-sg-id
今回の認証トークンの変更機能ですが、Redis 5.0.5以降でのサポートですので、それより上のエンジンバージョンにする必要があります。また、転送時の暗号化を有効にするためには以下のノードタイプしかサポートされていない点に注意です。
- R5、R4、R3
- M5、M4、M3
- T2
--transit-encryption-enabledというフラグは転送中の暗号化を有効にするフラグです。転送中の暗号化が有効になっていないとそもそもAUTHが設定できません。--auth-tokenで設定するトークンを指定します。こちらのトークンには以下の制約があります。
- トークンは 16 ~ 128 の印刷可能な文字であること
- 英数字以外の文字で使えるのは(!、&、#、$、^、<、>、-)のみ
なお、もっとセキュアに運用したいという方は、公式ドキュメントにて次のトークンポリシーに従うことが推奨されています。
- 以下の種類から 3 種類以上の文字が含まれている
- 英大文字
- 英小文字
- 数字
- アルファベット以外の文字 (!、&、#、$、^、<、>、-)
- 辞書に載っている単語またはそれを少し変更したような単語を使わない
- 最近使用したトークンと同じまたは類似したものは使わない
クラスターへの接続
今回はEC2(Amazon Linux 2)からredis-cliを用いました。redis-cliはSSLに対応していないので、転送中の暗号化を実現するには一工夫必要になります。普通に接続しようとしても接続が確立されないのです。
$ redis-cli -h master.test-modify-authkey.m6rlwr.apne1.cache.amazonaws.com -a password this-is-a-test-token Warning: Using a password with '-a' option on the command line interface may not be safe.
そのため、stunnelコマンドを使用してRedisノードへのSSLトンネルを作成します。まずはstunnelコマンドをインストールしましょう。
$ sudo yum install stunnel
次に/etc/stunnel/redis-cli.confファイルを作成し、以下のように設定を書きます。
$ cat /etc/stunnel/redis-cli.conf fips = no setuid = root setgid = root pid = /var/run/stunnel.pid debug = 7 delay = yes options = NO_SSLv2 options = NO_SSLv3 [redis-cli] client = yes accept = 127.0.0.1:6379 connect = [プライマリエンドポイント]:6379 [redis-cli-replica] client = yes accept = 127.0.0.1:6380 connect = [リーダーエンドポイント]:6379
続いてstunnelを起動してRedis clusterへのトンネルを掘ります。
$ sudo stunnel /etc/stunnel/redis-cli.conf
netstatを使って正しくstunnelが起動したかを確認します。
$ sudo netstat -tulnp | grep -i stunnel tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 4041/stunnel tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 4041/stunnel
これでRedisクラスターに無事接続が可能になります。
$ redis-cli -h localhost -p 6379 -a this-is-a-test-token localhost:6379> SET hoge bar OK
仮にトークンが間違っていた場合には次のようになります。
$ redis-cli -h localhost -p 6379 -a this-is-a-test-t Warning: Using a password with '-a' option on the command line interface may not be safe. localhost:6379> SET hoge bar (error) NOAUTH Authentication required.
Redisの認証トークンを変えてみる
認証トークンの変更には次のコマンドを使用します。
$ aws elasticache modify-replication-group \ --replication-group-id test-modify-authkey \ --auth-token This-is-the-rotated-token \ --auth-token-update-strategy ROTATE \ --apply-immediately
認証トークンが変わったことを確認しました。
$ redis-cli -h localhost -p 6379 -a This-is-the-rotated-token Warning: Using a password with '-a' option on the command line interface may not be safe. localhost:6379> SET neko nyan OK
ちなみに認証トークンは最大2つまで保持されます。よって、この状態であればまだ以前にキーで認証可能です。
$ redis-cli -h localhost -p 6379 -a this-is-a-test-token Warning: Using a password with '-a' option on the command line interface may not be safe. localhost:6379> SET hoge fuga OK
--auth-token-update-strategy SETを指定してmodify-replication-groupを実行することで、1つのAUTHトークンのみサポートするようにできます。
$ aws elasticache modify-replication-group \ --replication-group-id test-modify-authkey --auth-token This-is-the-rotated-token \ --auth-token-update-strategy SET \ --apply-immediately
最後に
いかがでしたでしょうか!結構長いことAUTHトークンを運用されている方はこれを機にローテートを検討されることをお勧めします。
以上、深澤(@shun_quartet)でした!